package com.todo.content.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.enums.EnableTypeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.StringUtils;
import com.todo.component.redis.RedisService;
import com.todo.content.application.convert.ContentConvert;
import com.todo.content.application.entity.bo.ContentTopicBO;
import com.todo.content.application.entity.bo.ContentTopicCountBO;
import com.todo.content.application.entity.condition.ContentTopicConditionBO;
import com.todo.content.application.service.ContentTopicService;
import com.todo.content.common.base.ContentKeyBuild;
import com.todo.content.infrastructure.entity.condition.ContentTopicCondition;
import com.todo.content.infrastructure.entity.po.ContentTopicPO;
import com.todo.content.infrastructure.repository.ContentTopicRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (ContentTopic)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 00:19:46
 */
@Slf4j
@Service("contentTopicService")
public class ContentTopicServiceImpl implements ContentTopicService {

    public static final int MAX_QUERY_COUNT = 100;

    @Resource
    private ContentTopicRepository contentTopicRepository;
    @Resource
    private RedisService redisService;

    @Override
    public Boolean insertContentTopic(ContentTopicBO contentTopicBO) {
        if (contentTopicBO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }

        //当前名称是否存在
        ContentTopicBO alreadyContentTopicBO = queryContentTopicByName(contentTopicBO.getName());
        if (alreadyContentTopicBO != null) {
            log.warn("ContentTopicService#insertContentTopic 新增内容话题失败，存在当前名称的话题信息 contentTopicBO：【{}】", JSONObject.toJSONString(contentTopicBO));
            throw new BizException(BizErrorCodeEnum.SAME_USER_NAME);
        }

        // 默认数量
        contentTopicBO.setContentCount(0);
        contentTopicBO.setJoinCount(0);
        contentTopicBO.setSeeCount(0);
        //默认禁用
        contentTopicBO.setIsEnable(EnableTypeEnum.FORBIDDEN);

        ContentTopicPO contentTopicPO = ContentConvert.convertToContentTopicPO(contentTopicBO);
        Boolean insertResult = contentTopicRepository.insertContentTopic(contentTopicPO);
        if (insertResult){
            String topicKey = ContentKeyBuild.buildContentTopicDetailKey(contentTopicBO.getTopicId());
            redisService.set(topicKey, JSONObject.toJSONString(contentTopicBO));
        }
        return insertResult;
    }

    @Override
    public Boolean updateContentTopic(ContentTopicBO contentTopicBO) {
        if (contentTopicBO == null || contentTopicBO.getTopicId() == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }

        ContentTopicBO alreadyContentTopicBO = queryContentTopicById(contentTopicBO.getTopicId());
        if (alreadyContentTopicBO == null) {
            log.warn("ContentTopicService#updateContentTopic 更新内容话题失败，不存在当前话题信息 contentTopicBO：【{}】", JSONObject.toJSONString(contentTopicBO));
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (EnableTypeEnum.FORBIDDEN == alreadyContentTopicBO.getIsEnable()) {
            log.warn("ContentTopicService#updateContentTopic 更新内容话题失败，当前话题非禁用状态无法修改 contentTopicBO：【{}】", JSONObject.toJSONString(contentTopicBO));
            throw new BizException(BizErrorCodeEnum.OPERATION_FAILED, "当前话题非禁用状态无法修改");
        }
        if (!alreadyContentTopicBO.getName().equals(contentTopicBO.getName())) {
            //当前名称是否存在
            ContentTopicBO sameNameContentTopicBO = queryContentTopicByName(contentTopicBO.getName());
            if (sameNameContentTopicBO != null) {
                log.warn("ContentTopicService#updateContentTopic 新增内容话题失败，存在当前名称的话题信息 contentTopicBO：【{}】", JSONObject.toJSONString(contentTopicBO));
                throw new BizException(BizErrorCodeEnum.SAME_USER_NAME);
            }
        }

        ContentTopicPO contentTopicPO = ContentConvert.convertToContentTopicPO(contentTopicBO);
        Boolean updateResult = contentTopicRepository.updateContentTopicById(contentTopicPO);
        if (updateResult) {
            String topicKey = ContentKeyBuild.buildContentTopicDetailKey(contentTopicBO.getTopicId());
            redisService.del(topicKey);
        }
        return updateResult;
    }

    @Override
    public Boolean removeContentTopicById(Long topicId) {
        if (topicId == null || topicId <= 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        Boolean removed = contentTopicRepository.removeContentTopicById(topicId);
        if (removed){
            String topicKey = ContentKeyBuild.buildContentTopicDetailKey(topicId);
            redisService.del(topicKey);
        }
        return removed;
    }

    @Override
    public ContentTopicBO queryContentTopicById(Long topic) {
        if (topic == null || topic <= 0) {
            return null;
        }
        String topicKey = ContentKeyBuild.buildContentTopicDetailKey(topic);
        if (redisService.hasKey(topicKey)) {
            return JSONObject.parseObject(redisService.get(topicKey), ContentTopicBO.class);
        }
        ContentTopicPO contentTopicPO = contentTopicRepository.queryContentTopicPOById(topic);
        ContentTopicBO contentTopicBO = ContentConvert.convertToContentTopicBO(contentTopicPO);
        redisService.set(topicKey, JSONObject.toJSONString(contentTopicBO));
        return contentTopicBO;
    }

    @Override
    public ContentTopicBO queryContentTopicByName(String name) {
        if (StringUtils.isBlank(name)) {
            return null;
        }
        ContentTopicPO contentTopicPO = contentTopicRepository.queryContentTopicByName(name);
        return ContentConvert.convertToContentTopicBO(contentTopicPO);
    }

    @Override
    public List<ContentTopicBO> searchContentTopicByName(String keyword) {
        if (StringUtils.isBlank(keyword)) {
            return Lists.newArrayList();
        }
        List<ContentTopicPO> contentTopicPOList = contentTopicRepository.searchContentTopicByName(keyword);
        if (CollectionUtils.isEmpty(contentTopicPOList)) {
            log.warn("ContentTopicService#searchContentTopicByName 根据话题名称搜索话题信息列表完成，数据为空 keyword：【{}】", keyword);
            return Lists.newArrayList();
        }
        return contentTopicPOList.stream().map(ContentConvert::convertToContentTopicBO).collect(Collectors.toList());
    }

    @Override
    public PageResult<ContentTopicBO> queryContentTopicListByCondition(ContentTopicConditionBO topicConditionBO) {
        if (topicConditionBO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentTopicCondition condition = ContentConvert.convertToContentTopicCondition(topicConditionBO);
        PageResult<ContentTopicPO> contentTopicPOPageResult = contentTopicRepository.queryContentTopicByCondition(condition);
        if (contentTopicPOPageResult == null) {
            log.warn("ContentTopicService#queryContentTopicListByCondition 多条件查询话题信息完成，数据为空  入参：【{}】", JSONObject.toJSONString(condition));
            return PageResult.of(Lists.newArrayList(), topicConditionBO.getPageIndex(), topicConditionBO.getPageSize(), 0L);
        }
        PageResult<ContentTopicBO> result = new PageResult<>();
        result.setCurrentIndex(contentTopicPOPageResult.getCurrentIndex());
        result.setResults(contentTopicPOPageResult.getResults() == null ? null : contentTopicPOPageResult.getResults().stream().map(ContentConvert::convertToContentTopicBO).collect(Collectors.toList()));
        result.setTotal(contentTopicPOPageResult.getTotal());
        result.setPageCount(contentTopicPOPageResult.getPageCount());
        result.setPageSize(contentTopicPOPageResult.getPageSize());
        result.setPageNum(contentTopicPOPageResult.getPageNum());
        return result;
    }

    @Override
    public List<ContentTopicBO> queryContentTopicByIdList(List<Long> topicIdList) {
        if (CollectionUtils.isEmpty(topicIdList)) {
            return Collections.emptyList();
        }
        if (topicIdList.size() > MAX_QUERY_COUNT) {
            log.warn("ContentTopicService#queryContentTopicByIdList 根据话题id列表查询话题信息列表完成，数据量过大 topicIdList：【{}】", JSONObject.toJSONString(topicIdList));
            throw new BizException(BizErrorCodeEnum.QUANTITY_EXPLOSION);
        }
        List<ContentTopicPO> contentTopicPOList = contentTopicRepository.queryContentTopicByIdList(topicIdList);
        if (CollectionUtils.isEmpty(contentTopicPOList)) {
            log.warn("ContentTopicService#queryContentTopicByIdList 根据话题id列表查询话题信息列表完成，数据为空 topicIdList：【{}】", JSONObject.toJSONString(topicIdList));
            return Collections.emptyList();
        }
        return contentTopicPOList.stream().map(ContentConvert::convertToContentTopicBO).collect(Collectors.toList());
    }

    @Override
    public Boolean enableContentTopicById(Long topicId, EnableTypeEnum enable) {
        if (topicId == null || topicId <= 0 || enable == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentTopicBO contentTopicBO = queryContentTopicById(topicId);
        if (contentTopicBO == null) {
            log.warn("ContentTopicService#enableContentTopicById 启禁用话题失败，查询数据为空 无法操作 topicId：【{}】", topicId);
            return false;
        }
        if (enable.equals(contentTopicBO.getIsEnable())) {
            return true;
        }
        Boolean updated = contentTopicRepository.enableContentTopicById(topicId, enable.getType());
        if (updated){
            String topicKey = ContentKeyBuild.buildContentTopicDetailKey(topicId);
            redisService.del(topicKey);
        }
        return updated;
    }

    @Override
    public Boolean updateContentTopicCount(ContentTopicCountBO topicCountBO) {
        if (topicCountBO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentTopicBO contentTopicBO = queryContentTopicById(topicCountBO.getTopicId());
        if (contentTopicBO == null) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        contentTopicBO.setContentCount(topicCountBO.getContentCount());
        contentTopicBO.setSeeCount(topicCountBO.getSeeCount());
        contentTopicBO.setJoinCount(topicCountBO.getJoinCount());

        ContentTopicPO contentTopicPO = ContentConvert.convertToContentTopicPO(contentTopicBO);
        Boolean updated = contentTopicRepository.updateContentTopicCount(contentTopicPO);
        if (updated) {
            redisService.set(ContentKeyBuild.buildContentTopicDetailKey(contentTopicPO.getId()), JSONObject.toJSONString(contentTopicBO));
        }
        return updated;
    }
}
